#include <iostream>
#include <string>
#include <memory>

using namespace std;

// class Fruit
// {
//     public:
//         virtual void show() = 0;
//         virtual ~Fruit(){}
// };

// class Apple : public Fruit
// {
//     public:
//         void show() override
//         {
//             cout << "我是一个苹果" <<endl;
//         }
// };

// class Banana : public Fruit
// {
//     public:
//         void show() override
//         {
//             cout << "我是一个香蕉" <<endl;
//         }
// };

// 简单工厂模式，
// class FruitFactory
// {
//     public:
//         static shared_ptr<Fruit> create(const string& name)
//         {
//             if(name == "苹果")
//                 return make_shared<Apple>();
//             else
//                 return make_shared<Banana>();
//         }
// };

// int main()
// {
//     shared_ptr<Fruit> fruit = FruitFactory::create("苹果");
//     fruit->show();
//     fruit = FruitFactory::create("香蕉");
//     fruit->show();

//     return 0;
// }

// 工厂方法模式
// class FruitFactory
// {
//     public:
//         virtual shared_ptr<Fruit> create() = 0;
//         virtual ~FruitFactory(){}
// };

// class AppleFactory : public FruitFactory
// {
//     shared_ptr<Fruit> create() override
//     {
//         return make_shared<Apple>();
//     }
// };

// class BananaFactory : public FruitFactory
// {
//     shared_ptr<Fruit> create() override
//     {
//         return make_shared<Banana>();
//     }
// };

// int main()
// {
//     shared_ptr<FruitFactory> appleFactory = make_shared<AppleFactory>();
//     shared_ptr<FruitFactory> bananaFactory = make_shared<BananaFactory>();
//     shared_ptr<Fruit> apple = appleFactory->create();
//     apple->show();
//     shared_ptr<Fruit> banana = bananaFactory->create();
//     banana->show();
//     return 0;
// }

// 抽象工厂模式
class Fruit
{
public:
    virtual void show() = 0;
    virtual ~Fruit() {}
};

class Apple : public Fruit
{
public:
    void show() override
    {
        cout << "我是一个苹果" << endl;
    }
};

class Banana : public Fruit
{
public:
    void show() override
    {
        cout << "我是一个香蕉" << endl;
    }
};

class Animal
{
public:
    virtual void voice() = 0;
};

class Dog : public Animal
{
public:
    void voice() override
    {
        cout << "汪汪汪~" << endl;
    }
};

class Panda : public Animal
{
public:
    void voice() override
    {
        cout << "嘤嘤嘤~" << endl;
    }
};

class Factory
{
public:
    virtual shared_ptr<Fruit> getFruit(const string& name) = 0;
    virtual shared_ptr<Animal> getAnimal(const string& name) = 0;
};

class FruitFactory : public Factory
{
public:
    shared_ptr<Fruit> getFruit(const string& name)override
    {
        if(name == "苹果") return make_shared<Apple>();
        else if(name == "香蕉") return make_shared<Banana>();
        else return shared_ptr<Fruit>();
    }
    shared_ptr<Animal> getAnimal(const string& name)override
    {
        return shared_ptr<Animal>();
    }
};

class AnimalFactory : public Factory
{
public:
    shared_ptr<Animal> getAnimal(const string& name)override
    {
        if(name == "小狗") return make_shared<Dog>();
        else if(name == "熊猫") return make_shared<Panda>();
        else return shared_ptr<Animal>();
    }
    shared_ptr<Fruit> getFruit(const string& name)override
    {
        return shared_ptr<Fruit>();
    }
};

class FactoryProducer {
    public:
        static std::shared_ptr<Factory> getFactory(const std::string &name) 
        {
            if (name == "动物") return std::make_shared<AnimalFactory>();
            else return std::make_shared<FruitFactory>();
        }
 };

 int main()
 {
    shared_ptr<Factory> animal_factory = FactoryProducer::getFactory("动物");
    shared_ptr<Animal> animal = animal_factory->getAnimal("小狗");
    animal->voice();
    animal = animal_factory->getAnimal("熊猫");
    animal->voice();


    shared_ptr<Factory> fruit_factory = FactoryProducer::getFactory("水果");
    shared_ptr<Fruit> fruit = fruit_factory->getFruit("苹果");
    fruit->show();
    fruit = fruit_factory->getFruit("香蕉");
    fruit->show();

    return 0;
 }